package com.vf.admin.client.controller.oldPay.wechat.controller;

import com.alibaba.fastjson.JSON;
import com.vf.admin.client.common.ClientConstants;
import com.vf.admin.client.common.RedisKeys;
import com.vf.admin.client.service.*;
import com.vf.admin.client.service.pay.WxPayService;
import com.vf.admin.common.BaseController;
import com.vf.admin.common.Constants;
import com.vf.admin.common.entity.Result;
import com.vf.admin.common.redis.RedisUtil;
import com.vf.admin.fiwork.controller.AppDailyTasController;
import com.vf.admin.miaodong.entity.*;
import com.vf.admin.utils.HttpClient;
import com.vf.admin.utils.MD5Util;
import com.vf.admin.utils.pay.ApiAplayWeChat.IpUtils;
import com.vf.admin.utils.pay.ApiAplayWeChat.PayUtil;
import com.vf.admin.utils.pay.ApiAplayWeChat.Signature;
import com.vf.admin.utils.pay.ApiAplayWeChat.WxPayConfig;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.*;

import static com.vf.admin.common.Constants.dingdan_status_dfk;
import static com.vf.admin.common.Constants.dingdan_zhiFuLeiXing_wx;
import static com.vf.admin.utils.RandomUtil.getOrderIdByUUId;

/**
 * 微信支付
 *
 * @author anxiang
 */
@Controller
@CrossOrigin
@RequestMapping(value = "/api/wechat/old")
public class ApiWeChatAplay extends BaseController {
    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    AppUserService appUserService;
    @Autowired
    private AppSetupService appSetupService;
    @Autowired
    private AppOrderService appOrderService;
    @Autowired
    private AppMingXiZuanShiService appMingXiZuanShiService;
    @Autowired
    private AppMingxiChongzhiService appMingxiChongzhiService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private AppDailyTasController appDailyTasController;
    @Autowired
    private AppInvitationRecordService appInvitationRecordService;
    @Autowired
    private AgentUserService agentUserService;
    @Autowired
    private VipOrderService vipOrderService;
    @Autowired
    WxPayService wxPayService;
    @Autowired
    AppPrivilegeService appPrivilegeService;
    @Autowired
    AppCzMoneyService appCzMoneyService;
//
//    private static volatile ApiWeChatAplay instance;
//    private static volatile AlipayClient alipayClient;

    /**
     * GATEWAYURL: 支付宝网关："https://openapi.alipay.com/gateway.do"
     * APPID: 创建应用后生成
     * APP_PRIVATE_KEY:开发者私钥
     * FORMAT:参数返回格式  JSON
     * CHARSET:UTF-8
     * ALIPAY_PUBLIC_KEY:支付宝公钥，支付宝生成
     * SIGN_TYPE:签名算法类型 RSA2
     */
//    private ApiWeChatAplay() {
//        alipayClient = new DefaultAlipayClient(AlipayConfig.GATEWAYURL, AlipayConfig.APPID, AlipayConfig.APP_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGN_TYPE);
//    }
//
//    public static ApiWeChatAplay getInstance() {
//        if (instance == null) {
//            synchronized (ApiWeChatAplay.class) {
//                if (instance == null) {
//                    instance = new ApiWeChatAplay();
//                }
//            }
//        }
//        return instance;
//    }

    /**
     * 钻石充值
     *
     * @param request
     * @param money   充值金额
     * @return
     */
    @RequestMapping(value = "/diamondRecharge")
    @ResponseBody
    public Result diamondRechargeWeChat(HttpServletRequest request, BigDecimal money, Integer id) {

        try {
            AppSetup setup = appSetupService.get();
            if (setup.getOpenRecharge() == 0) {
                return this.errorJSON(setup.getRechargeTip());
            }

            AppCzMoney appCzMoney = appCzMoneyService.get(id);
            String orderNo = getOrderIdByUUId();
            //添加订单记录
            AppOrder topup = new AppOrder();
            topup.setCreatetime(new Date());
            topup.setOrdernum(orderNo);//生成订单号
            topup.setCzMoneyId(id);
            topup.setMoney(new BigDecimal(appCzMoney.getMoney()));
            topup.setStatus(Constants.dingdan_status_dfk);//默认 1、代付款
            topup.setType(dingdan_zhiFuLeiXing_wx);//支付类型 2、微信支付

            //下单人信息
            AppUser user = appUserService.get((Integer) redisUtil.get(RedisKeys.userToken + request.getHeader(ClientConstants.client_toke)));
            topup.setUserid(user.getId());
            topup.setPic(user.getPic());
            topup.setNick(user.getNick());
            topup.setPhone(user.getLoginname());
            topup.setNum(appCzMoney.getDiamonds().add(appCzMoney.getGive()));
            appOrderService.save(topup);

            Map<String, String> params = new HashMap<>();
            params.put("body", "充值");
            params.put("orderNo", orderNo);
            params.put("money", money.stripTrailingZeros().toPlainString());
            params.put("notifyUrl", wxPayService.notify_url);
            params.put("payFrom", "APP");
            String result = HttpClient.doPost("http://127.0.0.1:8092/wxSign", params);
            Map<String, Object> signMap = JSON.parseObject(result, Map.class);
            return this.sucessJSON(signMap);
        } catch (Exception e) {
            e.printStackTrace();
            return this.errorJSON("服务器繁忙，请您稍后重试!");
        }
    }

    /**
     * 获取私钥。
     *
     * @param filename 私钥文件路径  (required)
     * @return 私钥对象
     */
    public static PrivateKey getPrivateKey(String filename) throws IOException {
        String content = new String(Files.readAllBytes(Paths.get(filename)), "utf-8");
        try {
            String privateKey = content.replace("-----BEGIN PRIVATE KEY-----", "")
                    .replace("-----END PRIVATE KEY-----", "")
                    .replaceAll("\\s+", "");

            KeyFactory kf = KeyFactory.getInstance("RSA");
            return kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey)));
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("当前Java环境不支持RSA", e);
        } catch (InvalidKeySpecException e) {
            throw new RuntimeException("无效的密钥格式");
        }
    }


    /**
     * 平台证书管理器
     */
    private static CertificatesManager certificatesManager;
    /**
     * 商户私钥
     */
    private static PrivateKey privateKey;

    /**
     * 如果你是使用Apache HttpClient的商户开发者，可以使用它构造HttpClient。得到的HttpClient在执行请求时将自动携带身份认证信息，并检查应答的微信支付签名。
     */
    private static CloseableHttpClient httpClient = null;
    /**
     * 商户id
     */
    private String mchId;
    /**
     * 商户序列号
     */
    private String mchSerialNo;
    /**
     * api_v3_key
     */
    private String apiV3Key;

    public static void init() throws IOException {
//        // 加载商户私钥（privateKey：私钥字符串）
//        privateKey = getPrivateKey("apiclient_key.pem文件地址");
//        // 获取证书管理器实例
//        certificatesManager = CertificatesManager.getInstance();
//        // 向证书管理器增加需要自动更新平台证书的商户信息
//        certificatesManager.putMerchant(WxPayConfig.mch_id, new WechatPay2Credentials(WxPayConfig.mch_id,
//                        new PrivateKeySigner(WxPayConfig.merchantSerialNumber, privateKey)),
//                WxPayConfig.key.getBytes(StandardCharsets.UTF_8));
//
//        // 初始化httpClient
//        httpClient = WechatPayHttpClientBuilder.create()
//                .withMerchant(WxPayConfig.mch_id, WxPayConfig.merchantSerialNumber, privateKey)
//                .withValidator(new WechatPay2Validator(certificatesManager.getVerifier(WxPayConfig.mch_id))).build();

        // 加载商户私钥（privateKey：私钥字符串）
        privateKey = PemUtil
                .loadPrivateKey(new ByteArrayInputStream(WxPayConfig.private_key.getBytes("utf-8")));

        // 加载平台证书（mchId：商户号,mchSerialNo：商户证书序列号,apiV3Key：V3密钥）
        AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
                new WechatPay2Credentials(WxPayConfig.mch_id, new PrivateKeySigner(WxPayConfig.mchSerialNo, privateKey)), WxPayConfig.apiV3Key.getBytes("utf-8"));

        // 初始化httpClient
        httpClient = WechatPayHttpClientBuilder.create()
                .withMerchant(WxPayConfig.mch_id, WxPayConfig.mchSerialNo, privateKey)
                .withValidator(new WechatPay2Validator(verifier)).build();

    }


//    static {
//        try {
//            init();
//        } catch (GeneralSecurityException e) {
//            throw new RuntimeException(e);
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        } catch (HttpCodeException e) {
//            throw new RuntimeException(e);
//        } catch (NotFoundException e) {
//            throw new RuntimeException(e);
//        }
//    }


    /**
     * 钻石充值H5
     *
     * @param request
     * @param productId 产品ID
     * @return
     */
    @RequestMapping(value = "/diamondRechargeWeb")
    @ResponseBody
    public Result diamondRechargeWeChatWeb(HttpServletRequest request, Integer productId) {

        try {
            init();
            AppSetup setup = appSetupService.get();
            if (setup.getOpenRecharge() == 0) {
                return this.errorJSON(setup.getRechargeTip());
            }

            AppCzMoney appCzMoney = appCzMoneyService.get(productId);
            String orderNo = getOrderIdByUUId();
            //添加订单记录
            AppOrder topup = new AppOrder();
            topup.setCreatetime(new Date());
            topup.setOrdernum(orderNo);//生成订单号
            topup.setCzMoneyId(productId);
            topup.setMoney(new BigDecimal(appCzMoney.getMoney()));
            topup.setStatus(Constants.dingdan_status_dfk);//默认 1、代付款
            topup.setType(dingdan_zhiFuLeiXing_wx);//支付类型 2、微信支付
            //下单人信息
            AppUser user = appUserService.get((Integer) redisUtil.get(RedisKeys.userToken + request.getHeader(ClientConstants.client_toke)));
            topup.setUserid(user.getId());
            topup.setPic(user.getPic());
            topup.setNick(user.getNick());
            topup.setPhone(user.getLoginname());
            topup.setNum(appCzMoney.getDiamonds().add(appCzMoney.getGive()));
            appOrderService.save(topup);
            String ip = IpUtils.getRealIp(request);
            HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/h5");
            // 请求body参数
//            int total = topup.getMoney().multiply(new BigDecimal(100)).intValue();//单位是分
            int total = 1;//单位是分
            String reqdata = "{"
                    + "\"amount\": {"
                    + "\"total\": " + total + ","
                    + "\"currency\": \"CNY\""
                    + "},"
                    + "\"scene_info\": {"
                    + "\"payer_client_ip\":\"" + ip + "\","
                    + "\"h5_info\": {"
                    + "\"type\": \"Android\"" + "}},"
                    + "\"mchid\": \"" + WxPayConfig.mch_id + "\","
                    + "\"description\":\"钻石充值\","
                    + "\"notify_url\": \"" + WxPayConfig.notify_url + "\","
                    + "\"out_trade_no\": \"" + orderNo + "\","
                    + "\"appid\": \"" + WxPayConfig.appid + "\"" + "}";
            StringEntity entity = new StringEntity(reqdata, "utf-8");
            entity.setContentType("application/json");
            httpPost.setEntity(entity);
            httpPost.setHeader("Accept", "application/json");
            //完成签名并执行请求
            CloseableHttpResponse response = httpClient.execute(httpPost);
            String signMap = "";
            try {
                int statusCode = response.getStatusLine().getStatusCode();
                if (statusCode == 200) {
                    signMap = EntityUtils.toString(response.getEntity());
                } else if (statusCode == 204) {
                    System.out.println("success");
                } else {
                    System.out.println("failed,resp code = " + statusCode + ",return body = " + EntityUtils.toString(response.getEntity()));
                    throw new IOException("request failed");
                }
            } finally {
                response.close();
            }
            return this.sucessJSON(signMap, "成功");
        } catch (Exception e) {
            e.printStackTrace();
            return this.errorJSON("服务器繁忙，请您稍后重试!");
        }
    }


    /**
     * @param code  订单编号
     * @param money 充值金额
     * @param body  充值备注
     * @return
     * @throws Exception
     */
    public static Map<String, String> getWechat(String notifyUrl, String code, int money, String body) {
        //生成的随机字符串
        String nonce_str = code;
        //获取本机的ip地址
        String spbill_create_ip = "127.0.0.1";
        SortedMap<Object, Object> packageParams = new TreeMap<>();
        packageParams.put("appid", WxPayConfig.appid);
        packageParams.put("mch_id", WxPayConfig.mch_id);
        packageParams.put("nonce_str", getWxTimeStamp());
        packageParams.put("sign_type", "MD5");

        packageParams.put("spbill_create_ip", spbill_create_ip);
        packageParams.put("body", body);
        packageParams.put("out_trade_no", nonce_str);//商户订单号
        packageParams.put("total_fee", String.valueOf(money));//支付金额，这边需要转成字符串类型，否则后面的签名会失败
        packageParams.put("notify_url", notifyUrl);//回调地址
        packageParams.put("trade_type", WxPayConfig.TRADETYPE);

        String sign = getSign("UTF-8", packageParams, WxPayConfig.key);
        packageParams.put("sign", sign);
        String requestXML = getRequestXml(packageParams);
        String resXml = postData(WxPayConfig.pay_url, requestXML);

        Map mapes = PayUtil.doXMLParse(resXml);
        //返回状态码
        String returnCode = (String) mapes.get("return_code");
        Map<String, String> response = new HashMap<String, String>(16);
        if ("SUCCESS".equals(returnCode)) {
            String prepayId = (String) mapes.get("prepay_id");//返回的预付单信息
            response.put("appid", WxPayConfig.appid);
            response.put("noncestr", nonce_str);
            response.put("package", "Sign=WXPay");
            response.put("prepayid", prepayId);
            Long timeStamp = System.currentTimeMillis() / 1000;
            response.put("timestamp", timeStamp + "");//这边要将返回的时间戳转化成字符串，不然小程序端调用wx.requestPayment方法会报签名错误
            response.put("partnerid", WxPayConfig.mch_id);
            response = PayUtil.paraFilter(response);
            String prestrdd = PayUtil.createLinkString(response);
            //System.out.println("二次签名数据" + prestrdd);
            String paySign = PayUtil.sign(prestrdd, WxPayConfig.key, "utf-8").toUpperCase();
            response.put("sign", paySign);
        }
        return response;
    }


    @RequestMapping(value = "/wxNotify/{from}")
    @ResponseBody
    public void wxNotify(HttpServletRequest request, HttpServletResponse response, @PathVariable("from") String from) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        //sb为微信返回的xml
        String notityXml = sb.toString();
        String resXml = "";
        System.out.println("接收到的报文：" + notityXml);

        Map map = PayUtil.doXMLParse(notityXml);

        String returnCode = (String) map.get("return_code");
        //System.out.println("接收到的报文 returnCode：" + returnCode);
        if ("SUCCESS".equals(returnCode)) {
            //验证签名是否正确
            SortedMap<String, String> packageParams = new TreeMap<String, String>();
            packageParams.put("appid", map.get("appid") != null ? map.get("appid").toString() : null);
            packageParams.put("attach", map.get("attach") != null ? map.get("attach").toString() : null);
            packageParams.put("bank_type", map.get("bank_type") != null ? map.get("bank_type").toString() : null);
            packageParams.put("cash_fee", map.get("cash_fee") != null ? map.get("cash_fee").toString() : null);
            packageParams.put("fee_type", map.get("fee_type") != null ? map.get("fee_type").toString() : null);
            packageParams.put("is_subscribe", map.get("is_subscribe") != null ? map.get("is_subscribe").toString() : null);
            packageParams.put("mch_id", map.get("mch_id") != null ? map.get("mch_id").toString() : null);
            packageParams.put("nonce_str", map.get("nonce_str") != null ? map.get("nonce_str").toString() : null);
            packageParams.put("openid", map.get("openid") != null ? map.get("openid").toString() : null);
            packageParams.put("out_trade_no", map.get("out_trade_no") != null ? map.get("out_trade_no").toString() : null);
            packageParams.put("result_code", map.get("result_code") != null ? map.get("result_code").toString() : null);
            packageParams.put("return_code", map.get("return_code") != null ? map.get("return_code").toString() : null);
            packageParams.put("time_end", map.get("time_end") != null ? map.get("time_end").toString() : null);
            packageParams.put("total_fee", map.get("total_fee") != null ? map.get("total_fee").toString() : null);
            packageParams.put("trade_type", map.get("trade_type") != null ? map.get("trade_type").toString() : null);
            packageParams.put("transaction_id", map.get("transaction_id") != null ? map.get("transaction_id").toString() : null);
            String sign = Signature.createSign(packageParams, WxPayConfig.key);

            System.out.println("根据参数本地签名 sign：" + sign + "   微信返回的签名：" + map.get("sign"));
            //根据微信官网的介绍，对回调的参数进行验签
            if (sign.equals(map.get("sign"))) {
                String orderNum = (String) map.get("out_trade_no");
                if (from.equalsIgnoreCase("VIP")) {
                    vipOrderService.successCall(orderNum);
                } else if (from.equalsIgnoreCase("RECHARGE")) {
                    AppOrder topup = appOrderService.getByOrdernum(orderNum, dingdan_zhiFuLeiXing_wx, dingdan_status_dfk);

                    //判断预订单是否存在
                    if (!StringUtils.isEmpty(topup)) {
                        AppUser user = appUserService.get(topup.getUserid());
                        //存在则更改预订单支付状态
                        appOrderService.updateStastusYzf(orderNum, 2);

                        BigDecimal getDiamond = topup.getNum();

                        //添加用户钻石金额
                        appUserService.updateZuanShi(user.getId(), getDiamond);
                        //增加用户累积充值金额
                        appUserService.updateLeijiChongzhi(user.getId(), topup.getMoney());
                        //添加钻石明细
                        appMingXiZuanShiService.addMingxi(user.getId(), getDiamond, 1, "充值");
                        //添加充值明细
                        appMingxiChongzhiService.addMingxi(user.getId(), getDiamond, 2, topup.getMoney(), orderNum,topup.getMobileSpec());
                        //完成充值任务
                        appDailyTasController.getAwardOnce(topup.getUserid(), ClientConstants.TaskOnce.RECHARGE_FIRST);
                        //如果有上级发放用户充值提成
                        addAward(topup);

                        agentUserService.shareMoneyRecharge(user.getId(), topup.getNum());

                        //升级贵族
                        appPrivilegeService.isUpLevel(user);
                    }
                }
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            } else {
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            }
        } else {
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        /*System.out.println(resXml);
        System.out.println("微信支付回调数据结束");*/

        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }



    @RequestMapping(value = "/wxNotify")
    @ResponseBody
    public void wxNotify() throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader((ServletInputStream) request.getInputStream()));
        String line = null;
        StringBuilder sb = new StringBuilder();
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        //sb为微信返回的xml
        String notityXml = sb.toString();
//                "<xml><appid><![CDATA[wxf885cb90f73c3f50]]></appid><bank_type><![CDATA[GDB_CREDIT]]></bank_type><cash_fee><![CDATA[10]]></cash_fee><fee_type><![CDATA[CNY]]></fee_type><is_subscribe><![CDATA[N]]></is_subscribe><mch_id><![CDATA[1601271278]]></mch_id><nonce_str><![CDATA[1649321326]]></nonce_str><openid><![CDATA[oSuch50XmCKNKmYGSXPlyNMaX5JM]]></openid><out_trade_no><![CDATA[1000001780134774]]></out_trade_no><result_code><![CDATA[SUCCESS]]></result_code><return_code><![CDATA[SUCCESS]]></return_code><sign><![CDATA[C6C1647BE3FBE1A241B6644DF1FB4900]]></sign><time_end><![CDATA[20220407164902]]></time_end><total_fee>10</total_fee><trade_type><![CDATA[APP]]></trade_type><transaction_id><![CDATA[4200001297202204076139737613]]></transaction_id></xml>";
        String resXml = "";
        System.out.println("接收到的报文：" + notityXml);

        Map map = PayUtil.doXMLParse(notityXml);

        String returnCode = (String) map.get("return_code");
        //System.out.println("接收到的报文 returnCode：" + returnCode);
        if ("SUCCESS".equals(returnCode)) {
            //验证签名是否正确
            SortedMap<String, String> packageParams = new TreeMap<String, String>();
            packageParams.put("appid", map.get("appid") != null ? map.get("appid").toString() : null);
            packageParams.put("attach", map.get("attach") != null ? map.get("attach").toString() : null);
            packageParams.put("bank_type", map.get("bank_type") != null ? map.get("bank_type").toString() : null);
            packageParams.put("cash_fee", map.get("cash_fee") != null ? map.get("cash_fee").toString() : null);
            packageParams.put("fee_type", map.get("fee_type") != null ? map.get("fee_type").toString() : null);
            packageParams.put("is_subscribe", map.get("is_subscribe") != null ? map.get("is_subscribe").toString() : null);
            packageParams.put("mch_id", map.get("mch_id") != null ? map.get("mch_id").toString() : null);
            packageParams.put("nonce_str", map.get("nonce_str") != null ? map.get("nonce_str").toString() : null);
            packageParams.put("openid", map.get("openid") != null ? map.get("openid").toString() : null);
            packageParams.put("out_trade_no", map.get("out_trade_no") != null ? map.get("out_trade_no").toString() : null);
            packageParams.put("result_code", map.get("result_code") != null ? map.get("result_code").toString() : null);
            packageParams.put("return_code", map.get("return_code") != null ? map.get("return_code").toString() : null);
            packageParams.put("time_end", map.get("time_end") != null ? map.get("time_end").toString() : null);
            packageParams.put("total_fee", map.get("total_fee") != null ? map.get("total_fee").toString() : null);
            packageParams.put("trade_type", map.get("trade_type") != null ? map.get("trade_type").toString() : null);
            packageParams.put("transaction_id", map.get("transaction_id") != null ? map.get("transaction_id").toString() : null);
            String sign = Signature.createSign(packageParams, WxPayConfig.key);

            System.out.println("根据参数本地签名 sign：" + sign + "   微信返回的签名：" + map.get("sign"));
            //根据微信官网的介绍，对回调的参数进行验签
            String orderNum = (String) map.get("out_trade_no");
            //if(sign.equals())
            AppOrder topup = appOrderService.getByOrdernum(orderNum, dingdan_zhiFuLeiXing_wx, dingdan_status_dfk);

            //判断预订单是否存在
            if (!StringUtils.isEmpty(topup)) {
                AppUser user = appUserService.get(topup.getUserid());
                //存在则更改预订单支付状态
                appOrderService.updateStastusYzf(orderNum, 2);

                BigDecimal getDiamond = topup.getNum();

                //添加用户钻石金额
                appUserService.updateZuanShi(user.getId(), getDiamond);
                //增加用户累积充值金额
                appUserService.updateLeijiChongzhi(user.getId(), topup.getMoney());
                //添加钻石明细
                appMingXiZuanShiService.addMingxi(user.getId(), getDiamond, 1, "充值");
                //添加充值明细
                appMingxiChongzhiService.addMingxi(user.getId(), getDiamond, 2, topup.getMoney(), orderNum,topup.getMobileSpec());
                //完成充值任务
                appDailyTasController.getAwardOnce(topup.getUserid(), ClientConstants.TaskOnce.RECHARGE_FIRST);
                //如果有上级发放用户充值提成
                addAward(topup);

                agentUserService.shareMoneyRecharge(user.getId(), topup.getNum());

                //升级贵族
                appPrivilegeService.isUpLevel(user);
            }
            resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";

        } else {
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        /*System.out.println(resXml);
        System.out.println("微信支付回调数据结束");*/

        BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
        out.write(resXml.getBytes());
        out.flush();
        out.close();
    }

    /**
     * 邀请用户充值增加父级提成
     *
     * @param order
     */
    public void addAward(AppOrder order) {
        AppInvitationRecord record = appInvitationRecordService.getShangji(order.getUserid());
        if (record != null) {
            AppSetup appSetup = appSetupService.get();
            BigDecimal divide = order.getNum().multiply(appSetup.getRechargeInvite()).setScale(2, BigDecimal.ROUND_HALF_UP);
            appUserService.addDiamonds(record.getPuserid(), divide, "邀请用户充值提成");
        }
    }

    /**
     * 微信时间戳
     */
    public static String getWxTimeStamp() {
        long time = new Date().getTime() / 1000;
        return String.valueOf(time);
    }

    /**
     * xs 支付
     */
    public static String malaixsPlay() {
/*

    merchant_code	[string]	是	商户账号
    merchant_order_no	[string]	是	商户订单号		456545645487
    pay_type	[string]	是	支付通道编码
    currency	[string]	是	币种		PHP
    name	[string]	是	姓名
    mobile	[string]	是			9431230031
    email	[string]	是
    amount	[string]	是		单位元	200
    notify_url	[string]	是	回调地址		https://www.xswiftpay.com/notify
    page_url	[string]	是	成功转向地址
    order_time	[number]	是	下单时间戳(到秒)		1663403467
    sign	[string]	是	签名
* */
        SortedMap<String, String> postPlayData = new TreeMap<String, String>();

//    postPlayData.put("merchant_code", );
//    postPlayData.put("merchant_order_no", );
//    postPlayData.put("pay_type", );
//    postPlayData.put("currency", );
//    postPlayData.put("name", );
//    postPlayData.put("mobile", );
//    postPlayData.put("email", );
//    postPlayData.put("amount", );
//    postPlayData.put("notify_url", );
//    postPlayData.put("page_url", );
//    postPlayData.put("order_time", );
//    postPlayData.put("sign", );


        return "";
    }


    /**
     * 参数加密
     *
     * @param characterEncoding 编码格式
     * @param packageParams     请求参数
     * @param API_KEY
     */
    public static String getSign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {
        StringBuffer sb = new StringBuffer();
        Set<Map.Entry<Object, Object>> es = packageParams.entrySet();
        Iterator<Map.Entry<Object, Object>> it = es.iterator();
        while (it.hasNext()) {
            Map.Entry<Object, Object> entry = it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + API_KEY);
        System.out.println("签名" + sb.toString());
        return MD5Util.MD5(sb.toString()).toUpperCase();
    }

    /**
     * 将请求参数转换为xml格式的string
     */
    public static String getRequestXml(SortedMap<Object, Object> parameters) {
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        Set<Map.Entry<Object, Object>> es = parameters.entrySet();
        Iterator<Map.Entry<Object, Object>> it = es.iterator();
        while (it.hasNext()) {
            Map.Entry<Object, Object> entry = it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {
                sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
            } else {
                sb.append("<" + k + ">" + v + "</" + k + ">");
            }
        }
        sb.append("</xml>");
        return sb.toString();
    }

    public static String postData(String urlStr, String data) {
        int CONNECT_TIMEOUT = 5000;
        String DEFAULT_ENCODING = "UTF-8";
        BufferedReader reader = null;
        try {
            URL url = new URL(urlStr);
            URLConnection conn = url.openConnection();
            conn.setDoOutput(true);
            conn.setConnectTimeout(CONNECT_TIMEOUT);
            conn.setReadTimeout(CONNECT_TIMEOUT);

            OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);
            if (data == null) {
                data = "";
            }
            writer.write(data);
            writer.flush();
            writer.close();
            reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
                sb.append("\r\n");
            }
            return sb.toString();
        } catch (IOException e) {
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
            }
        }
        return null;
    }
}
